/**
 * 1. new Promise时，需要传递一个 executor 执行器，执行器立刻执行
 * 2. executor 接受两个参数，分别是 resolve 和 reject
 * 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled
 * 4. promise 的状态一旦确认，就不会再改变
 * 5. promise 都有 then 方法，then 接收两个参数，分别是 promise 成功的回调 onFulfilled,
 *      和 promise 失败的回调 onRejected
 * 6. 如果调用 then 时，promise已经成功，则执行 onFulfilled，并将promise的值作为参数传递进去。
 *      如果promise已经失败，那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。
 *      如果promise的状态是pending，需要将onFulfilled和onRejected函数存放起来，等待状态确定后，再依次将对应的函数执行(发布订阅)
 * 7. then 的参数 onFulfilled 和 onRejected 可以缺省
 * 8. promise 可以then多次，promise 的then 方法返回一个 promise
 * 9. 如果 then 返回的是一个结果，那么就会把这个结果作为参数，传递给下一个then的成功的回调(onFulfilled)
 * 10. 如果 then 中抛出了异常，那么就会把这个异常作为参数，传递给下一个then的失败的回调(onRejected)
 * 11.如果 then 返回的是一个promise,那么需要等这个promise，那么会等这个promise执行完，promise如果成功，
 *   就走下一个then的成功，如果失败，就走下一个then的失败
 */
/**
 * PromiseA+ 2.1
 */
 const PENDING = 'pending';
 const FULFILLED = 'fulfilled';
 const REJECTED = 'rejected';
 function Promise_(executor) {
     let self = this;
     self.status = PENDING;
     self.onFulfilled = [];//成功的回调
     self.onRejected = []; //失败的回调
     //PromiseA+ 2.1
     function resolve(value) {
         if (self.status === PENDING) {
             self.status = FULFILLED;
             self.value = value;
             self.onFulfilled.forEach(fn => fn());//PromiseA+ 2.2.6.1
         }
     }
 
     function reject(reason) {
         if (self.status === PENDING) {
             self.status = REJECTED;
             self.reason = reason;
             self.onRejected.forEach(fn => fn());//PromiseA+ 2.2.6.2
         }
     }
 
     try {
         executor(resolve, reject);
     } catch (e) {
         reject(e);
     }
 }
 
 Promise_.prototype.then = function (onFulfilled, onRejected) {
     //PromiseA+ 2.2.1 / PromiseA+ 2.2.5 / PromiseA+ 2.2.7.3 / PromiseA+ 2.2.7.4
     onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
     onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
     let self = this;
     //PromiseA+ 2.2.7
     let promise2 = new Promise_((resolve, reject) => {
         if (self.status === FULFILLED) {
             //PromiseA+ 2.2.2
             //PromiseA+ 2.2.4 --- setTimeout
             setTimeout(() => {
                 try {
                     //PromiseA+ 2.2.7.1
                     let x = onFulfilled(self.value);
                     resolvePromise(promise2, x, resolve, reject);
                 } catch (e) {
                     //PromiseA+ 2.2.7.2
                     reject(e);
                 }
             });
         } else if (self.status === REJECTED) {
             //PromiseA+ 2.2.3
             setTimeout(() => {
                 try {
                     let x = onRejected(self.reason);
                     resolvePromise(promise2, x, resolve, reject);
                 } catch (e) {
                     reject(e);
                 }
             });
         } else if (self.status === PENDING) {
             self.onFulfilled.push(() => {
                 setTimeout(() => {
                     try {
                         let x = onFulfilled(self.value);
                         resolvePromise(promise2, x, resolve, reject);
                     } catch (e) {
                         reject(e);
                     }
                 });
             });
             self.onRejected.push(() => {
                 setTimeout(() => {
                     try {
                         let x = onRejected(self.reason);
                         resolvePromise(promise2, x, resolve, reject);
                     } catch (e) {
                         reject(e);
                     }
                 });
             });
         }
     });
     return promise2;
 }
 
 function resolvePromise(promise2, x, resolve, reject) {
     let self = this;
     //PromiseA+ 2.3.1
     if (promise2 === x) {
         reject(new TypeError('Chaining cycle'));
     }
     if (x && typeof x === 'object' || typeof x === 'function') {
         let used; //PromiseA+2.3.3.3.3 只能调用一次
         try {
             let then = x.then;
             if (typeof then === 'function') {
                 //PromiseA+2.3.3
                 then.call(x, (y) => {
                     //PromiseA+2.3.3.1
                     if (used) return;
                     used = true;
                     resolvePromise(promise2, y, resolve, reject);
                 }, (r) => {
                     //PromiseA+2.3.3.2
                     if (used) return;
                     used = true;
                     reject(r);
                 });
 
             }else{
                 //PromiseA+2.3.3.4
                 if (used) return;
                 used = true;
                 resolve(x);
             }
         } catch (e) {
             //PromiseA+ 2.3.3.2
             if (used) return;
             used = true;
             reject(e);
         }
     } else {
         //PromiseA+ 2.3.3.4
         resolve(x);
     }
 }
// export default {}

class PromiseKB{
  
}
//在手写的promiseXXX.js添加以下代码，其中改成自己定义promise.js名字
PromiseKB.defer = PromiseKB.deferred = function(){
let dfd = {};
dfd.promise = new Promise_((resolve, reject)=>{
  dfd.resolve = resolve;
  dfd.reject = reject;
});
return dfd;
}
module.exports =  PromiseKB